package com.hanlin.beforejavacodesummary.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.hanlin.beforejavacodesummary.pojo.otherentry.po.KafkaLParamDO;
import com.hanlin.beforejavacodesummary.pojo.otherentry.po.TokenCheckResponse;
import com.hanlin.beforejavacodesummary.pojo.otherentry.po.TokenDO;
import com.hanlin.beforejavacodesummary.pojo.otherentry.vo.TokenVO;
import com.hanlin.beforejavacodesummary.service.XmlDownLoadService;
import com.hanlin.beforejavacodesummary.utils.HttpClientUtil;
import com.sgcc.dc.master.util.SkipHttpsUtil;
import com.sgcc.dc.master.util.UUIDUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
//import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 *
 * @author: lijing
 * @since: 2025-10-28
 * @description:
 */
@Service
public class XmlDownLoadServiceImpl implements XmlDownLoadService {

    @Override
    public String downXml(Map<String,String> map) throws IOException {

        String savePath = map.get("savePath");
        String token = map.get("token");


        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss_SSS");
        String format = now.format(dtf);
        //拼接 完整 文件保存路径
        savePath = savePath + format + "\\";
        //写死的 url 地址，后面 弄到 配置文件中。
        String url = "http://127.0.0.1:8999/v1/endpoint";
        Map<String, String> params = new HashMap<>();
        //参数， 模拟的  没有使用这些 参数
        params.put("fileId", "123e4567-e89b-12d3-a456-426614174000");
        params.put("fileName", "diagnosis_report_2024-12-20.json");
        params.put("timestamp", "2024-12-20T10:20:30Z");
        //请求头
        Map<String, String> header = new HashMap<>();
        header.put("Authorization", "Bearer " + token);
        header.put("Content-Type", "application/json");
        String fullPath = "";
        //TODO 这里有问题，这个 get 请求是将 参数 拼到 url 后面，我看 文档里是将 参数 放到 请求体里，如果是放到 请求体中，后面再改。
        CloseableHttpResponse response = this.doGetHead(url, params, header);
        if (response != null) {
            byte[] byteArray = EntityUtils.toByteArray(response.getEntity());
            try (InputStream swapStream = new ByteArrayInputStream(byteArray)) {
                //文件名字
                String fileName  = "1.xml";
                saveXML(swapStream, fileName,savePath);
                fullPath = savePath + fileName;
                return fullPath;
            }finally {
                response.close();
            }
        }else {
            return null;
        }
    }

    private String saveXML(InputStream swapStream, String fileName, String savePath) {
        try (InputStream inputStream1 = swapStream) {
            // 生成唯一文件名
            String nameUUid = UUID.randomUUID().toString().replace("-", "") + ".xml";

            MultipartFile file = new MockMultipartFile(
                    fileName,
                    nameUUid,
                    "application/xml",
                    inputStream1
            );

            long size = file.getSize();
            if (size == 0) {
                throw new IOException("文件大小为0");
            }
            BigDecimal fileSize = BigDecimal.valueOf(size / (1024.0));
            // 获取上传文件的原始名称
            String originalFilename = FilenameUtils.getName(file.getOriginalFilename());
            // 文件的后缀
            String fileExtension = StringUtils.getFilenameExtension(originalFilename);

            // 读取文件内容为字节数组
            byte[] fileBytes;

            try (InputStream inputStream = file.getInputStream()) {

                fileBytes = IOUtils.toByteArray(inputStream);

            }
            Path targetDir = Paths.get(savePath);
            if (!Files.exists(targetDir)) {
                Files.createDirectories(targetDir);
            }
            Path targetPath = targetDir.resolve(fileName);
            try (InputStream byteArrayStream = new ByteArrayInputStream(fileBytes)) {
                Files.copy(byteArrayStream, targetPath, StandardCopyOption.REPLACE_EXISTING);
            }
            return "fileId";
        }  catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }




    private   CloseableHttpResponse  doGetHead(String url, Map<String, String> param,Map<String, String> header) {

        // 创建Httpclient对象
        CloseableHttpClient httpClient = (CloseableHttpClient) SkipHttpsUtil.wrapClient();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {

            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();
            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);

            if (header != null){
                Set<String> keySet = header.keySet();
                for (String key : keySet) {
                    httpGet.addHeader(key, header.get(key));
                }
            }
            // 执行请求
            response = httpClient.execute(httpGet);

            return response;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public TokenDO getToekn() {
        TokenDO tokenDO = new TokenDO();
        tokenDO.setAccess_token(UUIDUtils.getUUID());
        tokenDO.setCode("200");
        tokenDO.setJti(UUIDUtils.getUUID());
        tokenDO.setToken_type("all");
        tokenDO.setMessage("成功获取token");
        tokenDO.setScope("all");
        tokenDO.setExpires_in(200000);
        return tokenDO;
    }

    @Override
    public ResponseEntity<Resource> mockXmlEndpoint(Map<String, Object> map) {
        String fileName = map.get("fileName").toString();
        String failPath = map.get("failPath").toString();

        // 构建文件路径
        Path filePath = Paths.get(failPath).resolve(fileName);
        File file = filePath.toFile();

        // 检查文件是否存在
        if (!file.exists() || !file.isFile()) {
            return ResponseEntity.notFound().build();
        }
        // 检查文件扩展名
        if (!fileName.toLowerCase().endsWith(".xml")) {
            return ResponseEntity.badRequest().build();
        }
        Resource resource = new FileSystemResource(file);
        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION,
                "attachment; filename=\"" + fileName + "\"");
        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE);
        headers.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
        headers.add(HttpHeaders.PRAGMA, "no-cache");
        headers.add(HttpHeaders.EXPIRES, "0");
        return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_XML)
                .headers(headers)
                .contentLength(file.length())
                .body(resource);

    }


    @Override
    public String mockKafkaDealData(KafkaLParamDO kafkaLParamDO) throws Exception {
        String fileId = kafkaLParamDO.getFileId();
        String fileName = kafkaLParamDO.getFileName();
        String timestamp = kafkaLParamDO.getTimestamp();
        // 保存 kafka 数据入库

        //1.从 redis中 读取 token
        //1.1 没有读取到token
        //1.2 去获取token 然后去验证

        //2.redis 读取到 token
        //2.1 检验 token 是否有效
        // 2.2 有效直接用
        //2.3 无效 直接去获取 然后去 验证


        //获取token
        TokenVO tokenVO = new TokenVO();
        tokenVO.setGrant_type("client_credentials");
        tokenVO.setScope("all");
        tokenVO.setClient_id("admin");
        tokenVO.setClient_secret("admin");
        Map<String, Object> mapParams = convertToMap(tokenVO);


        // TODO 这个方法有问题，
        TokenDO tokenDO = getHttpToekn(mapParams);

        if (tokenDO != null && "200".equals(tokenDO.getCode())) {
            String accessToken = tokenDO.getAccess_token();
            //检验 token
            TokenCheckResponse tokenCheckResponse = checkTokenResult(accessToken);

            if (tokenCheckResponse != null && tokenCheckResponse.getActive()) {
                //token 有效
                //调用 xml下载接口
                Map<String,String> map = new HashMap<>();

                // 存放 保存的基础路径
                map.put("savePath","E:\\personCode\\LiJingJavaCodeAddress\\beforeJavaCodeSummary\\src\\main\\resources\\downloadxml\\");
                map.put("token", accessToken);
                String filePath = this.downXml(map);
                return filePath;

            }
        }else {
            //保存 失败 kafka 数据入库

        }
        return null;
    }

    private TokenCheckResponse checkTokenResult(String accessToken) {
        //检验 token
        String checkTokenUrl = "http://127.0.0.1:8999/v1/auth-service/oauth/check_token";

        Map<String, Object> checkTokenMapParams = new HashMap<>();
        checkTokenMapParams.put("token", accessToken);
        Map<String, String> checkTokenMapHeader = new HashMap<>();
        checkTokenMapHeader.put("Content-Type", "application/json");
        checkTokenMapHeader.put("Authorization", accessToken);
        String httpCheckTokenResult = HttpClientUtil.doPostJsonHead(checkTokenUrl, checkTokenMapParams, checkTokenMapHeader);
        TokenCheckResponse tokenCheckResponse = JSONObject.parseObject(httpCheckTokenResult, TokenCheckResponse.class);
        return tokenCheckResponse;
    }

    private TokenDO getHttpToekn(Map<String, Object> mapParams) {
        String url = "http://127.0.0.1:8999/v1/auth-service/oauth/token";

        Map<String, String> header = new HashMap<>();
        // TODO 文档中 是 设置为  application/x-www-form-urlencoded 但是报错：unsupported Media Type ，暂时 弄成了  application/json，后面再改
        header.put("Content-Type", "application/x-www-form-urlencoded");
        header.put("Content-Type", "application/json");

        String httpTokenResult = HttpClientUtil.doPostJsonHead(url, mapParams, header);
        //转换
        TokenDO tokenDO = JSONObject.parseObject(httpTokenResult, TokenDO.class);
        return tokenDO;
    }

    private Map<String, Object> convertToMap(Object obj) {
        Map<String, Object> map = new HashMap<>();
        try {
            Class<?> clazz = obj.getClass();
            for (Field field : clazz.getDeclaredFields()) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(obj));
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return map;
    }
}
